<?php

namespace Biz\service\springHomeDecActivity;

use Biz\model\springHomeDecActivity\LuckyCharmTicket as mLuckyCharmTicket;
use Doraemon\tools\Log;

class LuckyCharmTicketService
{

    /**
     * 兑换锦鲤券
     * @param $uid
     * @param $count
     * @return bool
     */
    public static function exchange($uid, $count)
    {
        try {
            if (!ActivityService::running()) {
                throw new \Exception('活动已结束！');
            }
            //获取用户当前砖块数
            $countArr = WishService::userBrickCount($uid);
            $lastExchangeBrickCount = $countArr['exchange_brick_count'];
            $unExchangeBrickCount = $countArr['unexchange_brick_count'];
            $exchangeBrickCount = $count * mLuckyCharmTicket::EXCHANGE_BRICK_COUNT;
            if ($unExchangeBrickCount < $exchangeBrickCount) {
                throw new \Exception('砖块数量不足！');
            }
            $exchangeData = [];
            $userTicketCount = mLuckyCharmTicket::getUserTicketCount($uid);
            $tickets = self::genTicketNo($uid, $userTicketCount, $count);
            $time = date('Y-m-d H:i:s', time());
            for ($i = 0; $i < $count; $i++) {
                $exchangeData[] = [
                    'uid' => $uid,
                    'ticket_no' => $tickets[$i],
                    'data_status' => mLuckyCharmTicket::STATUS_NORMAL,
                    'winning' => mLuckyCharmTicket::WINNING_NO,
                    'type' => mLuckyCharmTicket::TYPE_EXCHANGE,
                    'create_time' => $time,
                    'update_time' => $time,
                ];
            }
            if (empty($exchangeData) || $count != count($tickets)) {
                throw new \Exception('兑换锦鲤券失败！');
            }

            $nResult = mLuckyCharmTicket::action(function () use (
                $uid,
                $exchangeData,
                $exchangeBrickCount,
                $lastExchangeBrickCount
            ) {
                $result = mLuckyCharmTicket::exchangeTickets($exchangeData);
                if (!$result) {
                    return false;
                }
                $result = WishService::addExchangeBrickCount($uid, $exchangeBrickCount, $lastExchangeBrickCount);
                if (!$result) {
                    return false;
                }
                return true;
            });
            if (!$nResult) {
                throw new \Exception('执行兑换锦鲤券失败！');
            }
        } catch (\Exception $e) {
            $errData = [
                'message' => $e->getMessage(),
                'code' => $e->getCode(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
            ];
            Log::error('兑换锦鲤券失败', $errData);
            return false;
        }
        return true;

    }


    /**
     * 生成锦鲤券编号
     * @param $uid
     * @param $ownCount
     * @param $count
     * @return array
     */
    public static function genTicketNo($uid, $ownCount = 0, $count = 1, $tryCount = 0)
    {
        if ($tryCount > 5) {
            throw new \Exception('生成锦鲤券失败');
        }
        $codes = [];

        $padStr = base_convert(rand(0, 15), 10, 16);

        $uid = str_pad($uid, 9, $padStr, STR_PAD_RIGHT);

        for ($i = 1; $i < $count + 1; $i++) {

            $time = microtime(true);

            $salt = md5(uniqid(mt_rand(), true));

            $index = $ownCount + $i;

            $v = crc32($uid . $time . $index . $salt);

            $v = base_convert($v, 10, 16);

            $padChar = base_convert(rand(0, 15), 10, 16);

            $v = str_pad($v, 9, $padChar, STR_PAD_RIGHT);

            $codes[] = $v;
        }

        $codes = array_unique($codes);

        if ($count != count($codes) || self::ticketExsit($codes)) {
            $codes = self::genTicketNo($uid, $ownCount, $count, $tryCount++);
        }

        return $codes;
    }

    /**
     * ticket是否存在
     * @param $ticketNos
     * @return bool
     */
    public static function ticketExsit($ticketNos)
    {
        $where['ticket_no'] = $ticketNos;
        if (mLuckyCharmTicket::dataHas($where)) {
            return true;
        }
        return false;
    }

    /**
     * 获取可兑换数量
     * @param $uid
     * @return false|float|int
     */
    public static function unExchangeTicketCount($uid)
    {
        $unExchangeCount = 0;
        if (!ActivityService::running()) {
            return $unExchangeCount;
        }
        $countArr = WishService::userBrickCount($uid);
        $exchangeCount = $countArr['exchange_brick_count'];
        $brickCount = $countArr['brick_count'];
        if ($brickCount < mLuckyCharmTicket::EXCHANGE_BRICK_COUNT) {
            return $unExchangeCount;
        }
        $unExchangeCount = intval(floor(($brickCount - $exchangeCount) / mLuckyCharmTicket::EXCHANGE_BRICK_COUNT));
        return $unExchangeCount;
    }

    /**
     * 获取用户拥有的锦鲤券
     * @param $uid
     * @return array
     */
    public static function exchangedTickets($uid, $page = 1, $perPage = 20)
    {
        return mLuckyCharmTicket::pageGetUserTickets($uid, $page, $perPage);
    }


    /**
     * 获取用户的锦鲤券数量
     * @param $uid
     * @return int
     */
    public static function userTicketsCount(int $uid)
    {
        $where['uid'] = $uid;
        $where['data_status'] = mLuckyCharmTicket::STATUS_NORMAL;
        return mLuckyCharmTicket::dataCount($where);
    }


    /**
     * 给用户发放锦鲤券
     * @param $uids
     * @param $count 给每个用户发放的数量
     * @return bool
     */
    public static function giveLuckyTicketToUsers(array $uids, int $count = 1)
    {
        $tickets = [];
        $time = date('Y-m-d H:i:s', time());
        foreach ($uids as $uid) {
            $ownCount = mLuckyCharmTicket::getUserTicketCount($uid);
            $ticketNos = self::genTicketNo($uid, $ownCount, $count);
            foreach ($ticketNos as $ticketNo) {
                $tickets[] = [
                    'uid' => $uid,
                    'ticket_no' => $ticketNo,
                    'data_status' => mLuckyCharmTicket::STATUS_NORMAL,
                    'winning' => mLuckyCharmTicket::WINNING_NO,
                    'type' => mLuckyCharmTicket::TYPE_GIVE,
                    'create_time' => $time,
                    'update_time' => $time,
                ];
            }
        }
        $insertCount = mLuckyCharmTicket::dataMultiInsert($tickets);
        if ($insertCount > 0) {
            return true;
        }
        return false;
    }


}